using System.Diagnostics.CodeAnalysis;
using Quiki.ExpressionParsers;

namespace Quiki.ElementFormatters
{
    public class WikiTextBuilder
    {
        public WikiTextBuilder()
        {
            document = new WikiDocument (new WikiDocReference("builder"), null);
            document.RootElement = Root;
        }

        public WikiDocument Document
        {
            get { return document; }
        }

        public WikiTextElement Root
        {
            get { return rootElement; }
        }

        public WikiTextElement LastAddedElement
        {
            get { return lastAddedElement; }
        }

        public WikiTextBuilder Category (string categoryName)
        {
            WikiInternalLinkElement element = new WikiInternalLinkElement ()
            {
                Reference = new WikiDocReference (WikiDocReference.CategoryText + ":" + categoryName),
            };
            AddElement (element);
            return this;
        }

        [SuppressMessage ("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "0#")]
        public WikiTextBuilder ExternalLink (string url)
        {
            WikiTextElement element = new WikiTextElement (WikiTextElementType.ExternalLink);
            element.Properties["url"] = url;
            AddElement(element);
            return this;
        }

        [SuppressMessage ("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "0#")]
        public WikiTextBuilder ExternalLink (string url, string text)
        {
            WikiTextElement element = new WikiTextElement (WikiTextElementType.ExternalLink);
            element.Properties["url"] = url;
            element.Properties["text"] = text;
            AddElement (element);
            return this;
        }

        public WikiTextBuilder Heading(int level, string text)
        {
            WikiTextElement element = new WikiTextElement(WikiTextElementType.Heading, level, text);
            AddElement (element);
            return this;
        }

        public WikiTextBuilder Image(string imageName, params string[] parameters)
        {
            AddElement (new WikiImageElement(imageName, parameters));
            return this;
        }

        public WikiTextBuilder InternalLink (string reference, string text, bool exists)
        {
            WikiInternalLinkElement element = new WikiInternalLinkElement()
                                                  {
                                                      Reference = new WikiDocReference(reference),
                                                      LinkText = text,
                                                      Exists = exists,
                                                  };
            AddElement (element);
            return this;
        }

        public WikiTextBuilder NewLine()
        {
            AddElement (new WikiTextElement (WikiTextElementType.NewLine));
            return this;
        }

        [SuppressMessage ("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "P")]
        public WikiTextBuilder P (string text)
        {
            AddElement (new WikiTextElement(WikiTextElementType.Paragraph, 1, text));
            return this;
        }

        public WikiTextBuilder Pre(string text)
        {
            AddElement (new WikiTextElement (WikiTextElementType.Pre, 1, text));
            return this;
        }

        public WikiTextBuilder Template (string templateName, params string[] templateParameters)
        {
            WikiTemplateElement element = new WikiTemplateElement(templateName, templateParameters);
            AddElement (element);
            return this;
        }

        [SuppressMessage ("Microsoft.Naming", "CA1719:ParameterNamesShouldNotMatchMemberNames", MessageId = "0#")]
        public WikiTextBuilder Text (string text)
        {
            AddElement (new WikiTextElement (WikiTextElementType.Text, text));
            return this;
        }

        private void AddElement (WikiTextElement element)
        {
            rootElement.ChildElements.Add (element);
            lastAddedElement = element;
        }

        private WikiDocument document;
        private WikiTextElement rootElement = new WikiTextElement (WikiTextElementType.Root);
        private WikiTextElement lastAddedElement;
    }
}